<?php

namespace App\Models;

use Carbon\Carbon;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Response;

class GoodsOrder extends Model
{
	use HasDateTimeFormatter;
    protected $table = 'goods_orders';


    //订单创建类型
    const ORDER_CREATE_TYPE_AUTO = 0;
    const ORDER_CREATE_TYPE_GENERAL = 1;
    const ORDER_CREATE_TYPE_MAP = [
        self::ORDER_CREATE_TYPE_AUTO => '自动',
        self::ORDER_CREATE_TYPE_GENERAL => '手动',
    ];

    //订单状态
    const ORDER_UNPAID = 0; //未支付
    const ORDER_PAID = 1; //已支付/待发货
    const ORDER_NOT_RECEIVED = 2; //已发货/待收货
    const ORDER_REFUND = 3; //退款中
    const ORDER_REFUNDED = 4; //已退款
    const ORDER_CANCEL = 5; //取消
    const ORDER_TIME_OUT_CANCEL = 6; //超时取消
    const ORDER_END = 7; //完成
    const ORDER_SELL = 8; //二手卖出
    const ORDER_SELL_SUCCESS = 9; //二手卖出成功
    const ORDER_SELL_FAIL = 10; //二手卖出失败


    const ORDER_STATUS = [
        self::ORDER_UNPAID => '未支付',
        self::ORDER_PAID => '已支付/待发货',
        self::ORDER_NOT_RECEIVED => '已发货/待收货',
        //self::ORDER_REFUND => '退款中',
        //self::ORDER_REFUNDED => '已退款',
        self::ORDER_CANCEL => '取消',
        self::ORDER_TIME_OUT_CANCEL => '超时取消',
        self::ORDER_END => '完成',
        //self::ORDER_SELL => '二手卖出',
        //self::ORDER_SELL_SUCCESS => '二手卖出成功',
        //self::ORDER_SELL_FAIL => '二手卖出失败',
    ];


    protected $fillable = [
        'order_sn',
        'user_id',
        'order_status',
        'pay_time',
        'complete_time',
        'delivery_time',
        'remark',
        'order_create_type',
        'order_total_original_price',
        'order_total_price',
        'order_total_profit',
        'add_time'
    ];


    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function orderDetail()
    {
        return $this->HasMany(GoodsOrderDetail::class, 'order_id' ,'id');
    }

    //商品橱窗
    public function goodsLogistics()
    {
        return $this->hasMany(GoodsLogistic::class,'good_order_id','id');
    }

    /**
     * 创建订单
     * @param $user_id int 用户id
     * @param $amount int 订单金额
     * @param $type int 订单类型
     * @param $expiration_time int 超时时间（分）
     * @return GoodsOrder|\Illuminate\Database\Eloquent\Builder|Model|\LaravelIdea\Helper\App\Models\_IH_GoodsOrder_QB
     */
    public static function store(int $user_id, int $order_create_type, $order_total_original_price = 0, $order_total_price = 0, $order_total_profit = 0,$add_time)
    {
        if(!empty($add_time)){
            $add_time = Carbon::parse($add_time);
        }else{
            $add_time = now();
        }
        return self::query()->create([
            'order_sn' => only_code(),
            'user_id' => $user_id,
            'order_create_type' => $order_create_type,
            'order_total_original_price' => $order_total_original_price,
            'order_total_price' => $order_total_price,
            'order_total_profit' => $order_total_profit,
            'add_time' => $add_time
        ]);
    }


    /**
     * 支付
     * @param $order
     * @param User $user
     * @return \Illuminate\Database\Eloquent\HigherOrderBuilderProxy|int|mixed
     */
    public static function payment($order, User $user)
    {
        $order_total = 0;
        foreach ($order as $value) {
            //获取订单商品
            $goods_data = GoodsOrderDetail::getOrderGoodsByOrderId($value->id);
            $value->goods_data = $goods_data;
            $order_total = bcadd($order_total, $goods_data['order_total_original_price']);
        }

        $use_coupon = false;
        if(config('app.coupon_switch')){
            //如果开启了优惠卷,判断是否有可用优惠卷
            $coupons = Coupon::query()
                ->whereHas('coupon_config', function ($query) {
                    $query->where('state', 1);
                })
                ->with('coupon_config')
                ->where('user_id','=',$user->id)
                ->where('expiration_time','>',now())
                ->orderBy('coupon_config_id')
                ->get();
            if(!$coupons->isEmpty()){
                $discount_amount = 0;
                foreach ($coupons as $coupon){
                    $quota = $coupon->coupon_config->quota - $coupon->used_quota; //剩余额度
                    if($quota > 0){
                        //订单最大抵扣金额
                        $coupon->max_discount_amount = bcmul($order_total , $coupon->coupon_config->deduction_ratio / 100);
                        //实际抵扣金额
                        $coupon->discount_amount = $quota > $coupon->max_discount_amount?$coupon->max_discount_amount:$quota;
                        if($coupon->discount_amount > $discount_amount){
                            $discount_amount = $coupon->discount_amount;
                            $use_coupon = $coupon;
                        }
                    }
                }
            }
        }


        $order_ids = [];
        foreach ($order as $value) {
            //获取订单商品
            $goods_data = $value->goods_data;
            unset($value->goods_data);

            //修改订单状态
            $value->order_status = GoodsOrder::ORDER_PAID;
            $value->pay_time = Carbon::now();
            if($use_coupon === false){
                //扣用户余额
                if ($user->balance < $goods_data['order_total_original_price']) {
                    throw new HttpException(Response::HTTP_OK, trans('error.10016'), null, [], 10016);
                }
                $user->decrement('balance', $goods_data['order_total_original_price']);
                $user->save();
                //写金额流水
                (new Account())->store($user->id, -$goods_data['order_total_original_price'], Account::GOODS_ORDER_PAYMENT, 0, $value->id);
            }else{
                $order_ids[] = $value->id;
            }

            $value->save();

            //self::setLogistic($value,$goods_data);  //取消自动模拟物流信息，改为手动填写
            //写物流信息，模拟物流
        }

        //带优惠卷支付
        if($use_coupon !== false){
            //实际需要支付订单金额
            $payment_amount = bcsub($order_total,$discount_amount);
            if ($user->balance < $payment_amount) {
                throw new HttpException(Response::HTTP_OK, trans('error.10016'), null, [], 10016);
            }
            $user->decrement('balance', $payment_amount);
            $user->save();

            $use_coupon->increment('used_quota',$discount_amount);

            $coupons_log = CouponsLog::query()->create([
                'coupon_id' => $use_coupon->id,
                'order_total_amount' => $order_total,
                'discount_amount' => $discount_amount,
                'order_ids' => implode(',',$order_ids)
            ]);

            //写金额流水
            (new Account())->store($user->id, -$payment_amount, Account::GOODS_ORDER_PAYMENT, 0, $coupons_log->id);

        }


    }

    /**
     * 第一阶段
    等待物流取件

    第二阶段
    物流已取件，发往目的地

    第三阶段
    物流到达（随机取一个地址）
    到货时间到了

    买家已收货
     * */
    public static function setLogistic($order,$goods_data){
        //查到货时间
        $now  = Carbon::now();
        //$now  = Carbon::parse('2024-03-19 06:25:12');
        $goods_ids = array_column($goods_data['goods']->toArray(), 'goods_id');
        $arrival_day = Goods::query()->whereIn('id',$goods_ids)->max('arrival_day');
        $arrival_day = $arrival_day<3 ? 3:$arrival_day; //最小3天
        $arrival_hour = $arrival_day * 24 + rand(1,10);  //换算为小时计算 //随机加N小时确认收货
        $bai_hour = [8,9,10,11,12,13,14,15,16,17,18,19];
        //取出所有白天的时间,并随机分秒
        $all_time = [];
        for($h = 1;$h <= $arrival_hour; $h++){
            $i = rand(10,59);
            $s = rand(10,59);
            $hour = Carbon::parse($now->copy()->addHours($h)->format('Y-m-d H') . ":$i:$s");
            if(in_array($hour->copy()->format('H'),$bai_hour)){
                $all_time[] = $hour;
            }
        }


        //收货--最后一个时间
        //$arrival_hour_sum = count($all_time);
        //$complete_time = $all_time[$arrival_hour_sum-1];
        //unset($all_time[$arrival_hour_sum-1]);

        //发货 1到3小时  等待物流取件
        $h= rand(0,3);
        $delivery_time = $all_time[$h];
        array_splice($all_time,0,$h);

        //取件 发货后1到3小时
        $h = rand(1,3);
        $pickup_time = $all_time[$h];
        array_splice($all_time,0,$h);

        // 到货  收货前1到5小时
        //$h = rand(1,5);
        //$arrival_time = getNthLastElement($all_time,$h); //到货

        $order->delivery_time = $delivery_time;
        //$order->complete_time = $complete_time;
        $order->save();
        $address = "";
        //$shipping_address = ShippingAddress::query()->inRandomOrder()->first();
        //if($shipping_address){
        //    $address = $shipping_address->address;
        //}
        $logistics = [
            [
                'good_order_id' => $order->id,
                //'message'       => trans('validation.logistics')['delivery'],
                'messagesystem'       => 'delivery',
                'time'          => $delivery_time
            ],
            [
                'good_order_id' => $order->id,
                //'message'       => trans('validation.logistics')['pickup'],
                'messagesystem'       => 'pickup',
                'time'          => $pickup_time
            ]
            /*
            ,
            [
                'good_order_id' => $order->id,
                'message'       => sprintf(trans('validation.logistics')['arrival'],$address),
                'time'          => $arrival_time
            ]

            ,
            [
                'good_order_id' => $order->id,
                'message'       => trans('validation.logistics')['complete'],
                'time'          => $complete_time
            ]
            */
        ];
        GoodsLogistic::insert($logistics);

        //dump("发货delivery_time :".$delivery_time);
        //dump("取件pickup_time :".$pickup_time);
        //dump("到货arrival_time :".$arrival_time);
        //dump("收货：complete_time :".$complete_time);
    }


    /**
     * 获取订单列表
     * @param $user_id
     * @param $where
     * @param $whereIn
     * @param $page
     * @param $limit
     */
    public static function getList($user_id, $where, $whereIn, $page, $limit,$order_field,$order_turn)
    {
        $model = self::query()
            ->with([
                'orderDetail' => function ($query) {
                        $query->select('id', 'order_id', 'goods_id', 'category_id', 'name', 'img', 'number', 'original_price', 'price','profit', 'total_original_price', 'total_price', 'total_profit');
                    },
                'goodsLogistics'=>function($query){
                        $query->select('good_order_id','message','time','messagesystem','shipping_address_id')->where('time','<',now())->orderBy('time');
                    }
                ])
            ->where('add_time', '<',now())
            ->where('user_id', $user_id);
        if (!empty($where)) {
            $model->where($where);
        }
        if (!empty($whereIn)) {
            $model->whereIn($whereIn[0], $whereIn[1]);
        }
        return $model->offset($page)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->select('id', 'order_sn', 'order_status', 'add_time','pay_time','delivery_time','complete_time','order_total_original_price','order_total_price','order_total_profit')
            ->orderBy($order_field,$order_turn)
            ->get();
    }


    //订单完成
    public static function complete($goodsorder){
        DB::beginTransaction();
        try {
            $order = GoodsOrder::query()
                ->where('id', '=',$goodsorder->id)
                ->where('order_status', GoodsOrder::ORDER_NOT_RECEIVED)
                ->lockForUpdate()
                ->first();
            if (!$order) {
                DB::rollBack();
            }
            //修改订单状态
            $order->order_status = GoodsOrder::ORDER_END;
            User::query()->where('id','=',$order->user_id)->increment('balance', $order->order_total_price);
            //写金额流水
            (new Account())->store($order->user_id, $order->order_total_price, Account::GOODS_ORDER_REFUND, 0, $order->id);
            $order->save();

            //自动写入收货
            $logistics = [
                /*
                [
                    'good_order_id' => $order->id,
                    'message'       => sprintf(trans('validation.logistics')['arrival'],$address),
                    'time'          => $arrival_time
                ]
                ,
                */
                [
                    'good_order_id' => $order->id,
                    'messagesystem'       => 'complete',
                    'time'          => now()
                ]
            ];
            GoodsLogistic::insert($logistics);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            Log::info('商品订单完成失败：', ['msg' => $e->getMessage(), 'file' => $e->getFile(), 'page' => $e->getLine()]);
        }
    }



}
